module IPFS.Client.Command.Repo(
  getVersion,
  Version(..),
  getStat,
  gcAff,
  gc
) where
import Data.Argonaut (class DecodeJson, Json, decodeJson)
import Data.Argonaut.Decode ((.:))
import Data.BigInt (BigInt)
import Data.Either (Either)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Integral (toBigInt)
import Data.Maybe (Maybe(..))
import Data.Tuple (snd)
import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Effect.Aff (Aff)
import Foreign.Object as O
import IPFS.Client (Client)
import IPFS.Client.Command (Command, defCommand, genQSObject)
import IPFS.Client.Command.Common (RepoStat(..))
import IPFS.Client.Utils.SendRequest (execJsonCommand, execAffStreamJsonCommand, execEffectStreamJsonCommand)
import Network.HTTP as HTTP
import Node.StreamEx.Types as ST
import Prelude (class Show, Unit, bind, pure, show, unit, ($), (<$>))

------------------------Version------------------------------

versionCommand::Command
versionCommand = defCommand { path = "repo/version",args = Nothing, qs = O.empty}

data Version = Version {
  version::String
}

derive instance genericVersion :: Generic Version _
instance showVersion :: Show Version where
  show s = genericShow s

instance versionDecodeJson :: DecodeJson Version where
  decodeJson::Json -> Either String Version
  decodeJson json = do
    x <- decodeJson json
    v <- x .: "Version"
    pure $ Version {version:v}




getVersion::Client -> Aff (Either String Version)
getVersion client = execJsonCommand client versionCommand
 
------------------------Stat---------------------------------

statCommand::Command
statCommand = defCommand { path = "repo/stat",args = Nothing, qs = O.empty}

getStat::Client -> Aff (Either String RepoStat)
getStat client = execJsonCommand client statCommand

------------------------gc---------------------------------

gcCommand::Maybe Boolean -> Maybe Boolean ->  Command
gcCommand streamErrors quiet = defCommand { path = "repo/gc",
                                            args = Nothing,
                                            qs = genQSObject ["stream-errors" /\ (show <$> streamErrors),"quiet" /\ (show <$> quiet)] O.empty}

gcAff::Client -> Maybe Boolean -> Maybe Boolean ->  Aff (Either String (ST.Readable Json))
gcAff client streamErrors quiet = execAffStreamJsonCommand client $ gcCommand streamErrors quiet


gc::Client -> Maybe Boolean -> Maybe Boolean  -> (HTTP.Response -> Effect Unit) ->  (Either String Json -> Effect Unit) -> Effect Unit
gc client streamErrors quiet startCallback callback = do
  _ <- execEffectStreamJsonCommand client (gcCommand streamErrors quiet) startCallback callback
  pure unit